{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3a5e9d13",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import csv\n",
    "import numpy as np\n",
    "\n",
    "import mindspore as ms\n",
    "from mindspore import nn\n",
    "from mindspore import context\n",
    "from mindspore import dataset\n",
    "from mindspore.train.callback import LossMonitor\n",
    "from mindspore.common.api import ms_function\n",
    "from mindspore.ops import operations as P\n",
    "\n",
    "context.set_context(mode=context.GRAPH_MODE, device_target=\"CPU\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8f506b15",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[['5.0', '3.5', '1.3', '0.3', 'Iris-setosa'], ['4.5', '2.3', '1.3', '0.3', 'Iris-setosa'], ['4.4', '3.2', '1.3', '0.2', 'Iris-setosa'], ['5.0', '3.5', '1.6', '0.6', 'Iris-setosa'], ['5.1', '3.8', '1.9', '0.4', 'Iris-setosa'], ['4.8', '3.0', '1.4', '0.3', 'Iris-setosa'], ['5.1', '3.8', '1.6', '0.2', 'Iris-setosa'], ['4.6', '3.2', '1.4', '0.2', 'Iris-setosa'], ['5.3', '3.7', '1.5', '0.2', 'Iris-setosa'], ['5.0', '3.3', '1.4', '0.2', 'Iris-setosa'], ['7.0', '3.2', '4.7', '1.4', 'Iris-versicolor'], ['6.4', '3.2', '4.5', '1.5', 'Iris-versicolor'], ['6.9', '3.1', '4.9', '1.5', 'Iris-versicolor'], ['5.5', '2.3', '4.0', '1.3', 'Iris-versicolor'], ['6.5', '2.8', '4.6', '1.5', 'Iris-versicolor'], ['5.7', '2.8', '4.5', '1.3', 'Iris-versicolor'], ['6.3', '3.3', '4.7', '1.6', 'Iris-versicolor'], ['4.9', '2.4', '3.3', '1.0', 'Iris-versicolor'], ['6.6', '2.9', '4.6', '1.3', 'Iris-versicolor'], ['5.2', '2.7', '3.9', '1.4', 'Iris-versicolor']]\n"
     ]
    }
   ],
   "source": [
    "with open('iris.data') as csv_file:\n",
    "    data = list(csv.reader(csv_file, delimiter=','))\n",
    "print(data[40:60]) # 打印部分数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d779076f",
   "metadata": {},
   "outputs": [],
   "source": [
    "label_map = {\n",
    "    'Iris-setosa': 0,\n",
    "    'Iris-versicolor': 1,\n",
    "}\n",
    "\n",
    "X = np.array([[float(x) for x in s[:-1]] for s in data[:100]], np.float32)\n",
    "Y = np.array([[label_map[s[-1]]] for s in data[:100]], np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "098a5d76",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x7f2b677e1090>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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v7+/wX7i4uL0/+/h4YHOnTvjzJkz+mUrV67EJ598gsuXL6OsrAzl5eXo0KFDjeM+deoUjhw5ggULFuiXaTQa3LlzB7dv30bdunUBAO3atdOvf+ihh+Dn54fCwkIAwLlz59ClSxeD/Xbt2tXiGO7ft0qlglqt1u+biOyDyQ0RVcvd3R1paWk4evQo9u3bh3/+859488038f333+sThNWrV+ORRx6psp2lNm7ciNdffx1Lly5FXFwcfH19sWTJEnz//fc1jru0tBSJiYl4+umnq6zz8fHR/7+np6fBOpVKBa1WW+Ofez977puIjGNyQ0QWUalU6NGjB3r06IG33noLYWFh2LZtG1577TU0atQIly5dwujRo83u49ixY+jVqxcA3ZWdEydOYOrUqQCAI0eOoHv37njllVf07S9evGhTzLGxsTh37hxatGhR4320atUKu3fvNliWkZFh8N7LywsajabGP4OI5MXkhoiq9f333+PAgQPo378/goKC8P333+O///0v2rRpAwBITEzEtGnT4O/vj4EDB+Lu3bv44YcfcOPGDbz22mv6/axcuRKRkZFo06YN3n//fdy4cQMvvvgiACAyMhLr1q3D3r17ERERgU8//RQZGRmIiIiocdxvvfUWnnjiCTRt2hTPPvss3NzccOrUKZw+fRrvvPOORft46aWX8N5772HmzJmYOHEiMjMzkZKSAkCX8AG6yfpKS0tx4MABtG/fHnXr1tVf0SIix+Oj4ERULT8/Pxw+fBiDBw9Gy5YtMXv2bCxduhSDBg0CAEyaNAkff/wx1qxZg5iYGPTu3RspKSlVEpOFCxdi4cKFaN++Pf79739j586dePjhhwHokoinn34aI0eOxCOPPIJr164ZXMWpiQEDBuDLL7/Evn370KVLF3Tr1g3vv/8+wsLCLN5HREQENm/ejK1bt6Jdu3ZITk7Gm2++CQDw9vYGAHTv3h0vv/wyRo4ciYYNG2Lx4sU2xU1EtlFJkiQ5OwgiUrbc3FxERETgxx9/tGmAsCgWLFiADz/8EFeuXHF2KERkBG9LERFV41//+he6dOmCBg0a4MiRI1iyZIl+rBARiYfJDRFRNS5cuIB33nkH169fR9OmTfGXv/wFs2bNcnZYRGQCb0sRERGRonBAMRERESkKkxsiIiJSFCY3REREpChMboiIiEhRmNwQERGRojC5ISIiIkVhckNERESKwuSGiIiIFOX/A0QZ62e+NdfYAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "plt.scatter(X[:50, 0], X[:50, 1], label='Iris-setosa')\n",
    "plt.scatter(X[50:, 0], X[50:, 1], label='Iris-versicolor')\n",
    "plt.xlabel('sepal length')\n",
    "plt.ylabel('sepal width')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bf196e0f",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_idx = np.random.choice(100, 80, replace=False)\n",
    "test_idx = np.array(list(set(range(100)) - set(train_idx)))\n",
    "X_train, Y_train = X[train_idx], Y[train_idx]\n",
    "X_test, Y_test = X[test_idx], Y[test_idx]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "5a00abec",
   "metadata": {},
   "outputs": [],
   "source": [
    "XY_train = list(zip(X_train, Y_train))\n",
    "ds_train = dataset.GeneratorDataset(XY_train, ['x', 'y'])\n",
    "# ds_train.set_dataset_size(80)\n",
    "ds_train = ds_train.shuffle(buffer_size=80).batch(32, drop_remainder=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "9931b4a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[WARNING] DEBUG(21603,7f2bcde33740,python):2023-01-10-23:40:46.943.385 [mindspore/ccsrc/debug/debugger/debugger.cc:92] Debugger] Not enabling debugger. Debugger does not support CPU.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'p')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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QFAh3AAAgKBCuAEAAEGFcAMAAIIK4aYFfv/732vEiBGKiYlRYmJig30KCgp04403KiYmRikpKfr1r3+t6urqJl/3yJEjuv322xUfH6/ExERNnDhRx48fb4MtaJmlS5fKZrM1+Fi9enWj61111VVn9L/33nt9WHnzZWZmnlHr008/3eQ6FRUVmjRpkjp06KDY2Fj96Ec/UlFRkY8qbpn8/HxNnDhR3bp1U3R0tHr06KFp06bJ5XI1uZ4/78NZs2YpMzNTUVFRysrK0qpVq5rs/95776lv376KiopS//79tXDhQh9V2nLTp0/XsGHDFBcXp5SUFN1yyy3aunVrk+vMnz//jH0VFRXlo4pb5ne/+90Ztfbt27fJdQJp/0kNf6bYbDZNmjSpwf7+vv+++OIL3XTTTUpPT5fNZtMHH3xQb7kxRlOnTlWnTp0UHR2tnJwcbd++/ayv29L3cUsRblrA5XLp1ltv1X333dfgcrfbrRtvvFEul0srVqzQG2+8ofnz52vq1KlNvu7tt9+uTZs26ZNPPtE///lPffHFF/rZz37WFpvQIiNGjNCBAwfqPe6++25169ZNQ4cObXLde+65p956zzzzjI+qbrknnniiXq33339/k/0feugh/eMf/9B7772nzz//XPv379cPf/hDH1XbMlu2bJHH49Err7yiTZs26YUXXtDs2bP1m9/85qzr+uM+XLBggSZPnqxp06Zp3bp1GjhwoEaNGqWDBw822H/FihUaO3asJk6cqPXr1+uWW27RLbfcoo0bN/q48ub5/PPPNWnSJH311Vf65JNPVFVVpeuuu05lZWVNrhcfH19vX+3evdtHFbfcxRdfXK/WZcuWNdo30PafJK1evbre9n3yySeSpFtvvbXRdfx5/5WVlWngwIGaNWtWg8ufeeYZ/fd//7dmz56tlStXql27dho1apQqKioafc2Wvo/PiUGLzZs3zyQkJJzRvnDhQmO3201hYaG37eWXXzbx8fGmsrKywdf67rvvjCSzevVqb9v//d//GZvNZvbt29fqtZ8Pl8tlOnbsaJ544okm+1155ZXmgQce8E1R56lr167mhRdeaHb/Y8eOmYiICPPee+952zZv3mwkmdzc3DaosPU988wzplu3bk328dd9OHz4cDNp0iTvc7fbbdLT08306dMb7P/jH//Y3HjjjfXasrKyzM9//vM2rbO1HDx40Egyn3/+eaN9Gvs88kfTpk0zAwcObHb/QN9/xhjzwAMPmB49ehiPx9Pg8kDaf5LM3/72N+9zj8dj0tLSzLPPPuttO3bsmHE4HOYvf/lLo6/T0vfxueDITSvKzc1V//79lZqa6m0bNWqUnE6nNm3a1Og6iYmJ9Y6E5OTkyG63a+XKlW1ec0v8/e9/1+HDhzVhwoSz9v3zn/+s5ORk9evXT1OmTNGJEyd8UOG5efrpp9WhQwcNHjxYzz77bJOnEdeuXauqqirl5OR42/r27asuXbooNzfXF+Wet5KSEiUlJZ21n7/tQ5fLpbVr19b7u7fb7crJyWn07z43N7def6nmPRlI+0rSWffX8ePH1bVrV2VkZOjmm29u9PPGH2zfvl3p6enq3r27br/9dhUUFDTaN9D3n8vl0ltvvaW77rqryYmaA2n/nSovL0+FhYX19lFCQoKysrIa3Ufn8j4+FyE3cWZbKiwsrBdsJHmfFxYWNrpOSkpKvbbw8HAlJSU1uo5V5syZo1GjRp114tHbbrtNXbt2VXp6ur755hs98sgj2rp1q/7617/6qNLm+9WvfqVLLrlESUlJWrFihaZMmaIDBw5oxowZDfYvLCxUZGTkGWOuUlNT/W5/NWTHjh168cUX9dxzzzXZzx/3YXFxsdxud4PvsS1btjS4TmPvyUDYVx6PRw8++KBGjhypfv36NdqvT58+mjt3rgYMGKCSkhI999xzGjFihDZt2tTmkwS3VFZWlubPn68+ffrowIEDevzxx3X55Zdr48aNiouLO6N/IO8/Sfrggw907Ngx3XnnnY32CaT9d7q6/dCSfXQu7+NzEfLh5tFHH9Uf/vCHJvts3rz5rIPeAsm5bPPevXv18ccf69133z3r6586Xqh///7q1KmTrr32Wu3cuVM9evQ498KbqSXbN3nyZG/bgAEDFBkZqZ///OeaPn26X98e/Vz24b59+3T99dfr1ltv1T333NPkulbvQ0iTJk3Sxo0bmxyTIknZ2dnKzs72Ph8xYoQuvPBCvfLKK3ryySfbuswWGT16tPfnAQMGKCsrS127dtW7776riRMnWlhZ25gzZ45Gjx6t9PT0RvsE0v4LJCEfbh5++OEmU7Ukde/evVmvlZaWdsaI77qraNLS0hpd5/RBVNXV1Tpy5Eij65yvc9nmefPmqUOHDvrBD37Q4t+XlZUlqeaogS++GM9nn2ZlZam6ulr5+fnq06fPGcvT0tLkcrl07NixekdvioqK2mx/NaSl27h//35dffXVGjFihF599dUW/z5f78OGJCcnKyws7Iwr05r6u09LS2tRf3/xy1/+0ntxQUv/9x4REaHBgwdrx44dbVRd60lMTFTv3r0brTVQ958k7d69W59++mmLj3YG0v6r2w9FRUXq1KmTt72oqEiDBg1qcJ1zeR+fk1YbvRNCzjaguKioyNv2yiuvmPj4eFNRUdHga9UNKF6zZo237eOPP/arAcUej8d069bNPPzww+e0/rJly4wk8/XXX7dyZa3vrbfeMna73Rw5cqTB5XUDit9//31v25YtW/x6QPHevXtNr169zE9+8hNTXV19Tq/hL/tw+PDh5pe//KX3udvtNp07d25yQPH3v//9em3Z2dl+OyDV4/GYSZMmmfT0dLNt27Zzeo3q6mrTp08f89BDD7Vyda2vtLTUtG/f3vzxj39scHmg7b9TTZs2zaSlpZmqqqoWrefP+0+NDCh+7rnnvG0lJSXNGlDckvfxOdXaaq8UAnbv3m3Wr19vHn/8cRMbG2vWr19v1q9fb0pLS40xNf8o+/XrZ6677jqzYcMGs2jRItOxY0czZcoU72usXLnS9OnTx+zdu9fbdv3115vBgweblStXmmXLlplevXqZsWPH+nz7GvPpp58aSWbz5s1nLNu7d6/p06ePWblypTHGmB07dpgnnnjCrFmzxuTl5ZkPP/zQdO/e3VxxxRW+LvusVqxYYV544QWzYcMGs3PnTvPWW2+Zjh07mnHjxnn7nL59xhhz7733mi5dupjPPvvMrFmzxmRnZ5vs7GwrNuGs9u7da3r27GmuvfZas3fvXnPgwAHv49Q+gbIP33nnHeNwOMz8+fPNd999Z372s5+ZxMRE7xWKd9xxh3n00Ue9/ZcvX27Cw8PNc889ZzZv3mymTZtmIiIizLfffmvVJjTpvvvuMwkJCWbp0qX19tWJEye8fU7fxscff9x8/PHHZufOnWbt2rXmJz/5iYmKijKbNm2yYhOa9PDDD5ulS5eavLw8s3z5cpOTk2OSk5PNwYMHjTGBv//quN1u06VLF/PII4+csSzQ9l9paan3u06SmTFjhlm/fr3ZvXu3McaYp59+2iQmJpoPP/zQfPPNN+bmm2823bp1M+Xl5d7XuOaaa8yLL77ofX6293FrINy0wPjx442kMx5Llizx9snPzzejR4820dHRJjk52Tz88MP1kvuSJUuMJJOXl+dtO3z4sBk7dqyJjY018fHxZsKECd7A5A/Gjh1rRowY0eCyvLy8en8HBQUF5oorrjBJSUnG4XCYnj17ml//+tempKTEhxU3z9q1a01WVpZJSEgwUVFR5sILLzRPPfVUvaNsp2+fMcaUl5ebX/ziF6Z9+/YmJibG/Nu//Vu9sOBP5s2b1+C/2VMP2gbaPnzxxRdNly5dTGRkpBk+fLj56quvvMuuvPJKM378+Hr93333XdO7d28TGRlpLr74YvPRRx/5uOLma2xfzZs3z9vn9G188MEHvX8fqamp5oYbbjDr1q3zffHNMGbMGNOpUycTGRlpOnfubMaMGWN27NjhXR7o+6/Oxx9/bCSZrVu3nrEs0PZf3XfW6Y+6bfB4POaxxx4zqampxuFwmGuvvfaM7e7atauZNm1avbam3setwWaMMa13kgsAAMBa3OcGAAAEFcINAAAIKoQbAAAQVAg3AAAgqBBuAABAUCHcAACAoEK4AQAAQYVwAwAAggrhBgAABBXCDQAACCqEGwAAEFQINwAC3qFDh5SWlqannnrK27ZixQpFRkZq8eLFFlYGwApMnAkgKCxcuFC33HKLVqxYoT59+mjQoEG6+eabNWPGDKtLA+BjhBsAQWPSpEn69NNPNXToUH377bdavXq1HA6H1WUB8DHCDYCgUV5ern79+mnPnj1au3at+vfvb3VJACzAmBsAQWPnzp3av3+/PB6P8vPzrS4HgEU4cgMgKLhcLg0fPlyDBg1Snz59NHPmTH377bdKSUmxujQAPka4ARAUfv3rX+v999/X119/rdjYWF155ZVKSEjQP//5T6tLA+BjnJYCEPCWLl2qmTNn6s0331R8fLzsdrvefPNNffnll3r55ZetLg+Aj3HkBgAABBWO3AAAgKBCuAEAAEGFcAMAAIIK4QYAAAQVwg0AAAgqhBsAABBUCDcAACCoEG4AAEBQIdwAAICgQrgBAABBhXADAACCyv8Hi0OYEPIDlRkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "coor_x = np.arange(-10, 11, dtype=np.float32)\n",
    "coor_y = nn.Sigmoid()(ms.Tensor(coor_x)).asnumpy()\n",
    "plt.plot(coor_x, coor_y)\n",
    "plt.xlabel('x')\n",
    "plt.ylabel('p')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "b0e38957",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch: 1 step: 2, loss is 0.6635994\n",
      "epoch: 2 step: 2, loss is 0.5750566\n",
      "epoch: 3 step: 2, loss is 0.50785065\n",
      "epoch: 4 step: 2, loss is 0.45378023\n",
      "epoch: 5 step: 2, loss is 0.41713428\n",
      "epoch: 6 step: 2, loss is 0.37348443\n",
      "epoch: 7 step: 2, loss is 0.38700023\n",
      "epoch: 8 step: 2, loss is 0.349527\n",
      "epoch: 9 step: 2, loss is 0.2944227\n",
      "epoch: 10 step: 2, loss is 0.28608647\n"
     ]
    }
   ],
   "source": [
    "# 自定义Loss\n",
    "class Loss(nn.Cell):\n",
    "    def __init__(self):\n",
    "        super(Loss, self).__init__()\n",
    "        self.sigmoid_cross_entropy_with_logits = P.SigmoidCrossEntropyWithLogits()\n",
    "        self.reduce_mean = P.ReduceMean(keep_dims=False)\n",
    "    def construct(self, x, y):\n",
    "        loss = self.sigmoid_cross_entropy_with_logits(x, y)\n",
    "        return self.reduce_mean(loss, -1)\n",
    "\n",
    "net = nn.Dense(4, 1)\n",
    "loss = Loss()\n",
    "opt = nn.optim.SGD(net.trainable_params(), learning_rate=0.003)\n",
    "model = ms.train.Model(net, loss, opt)\n",
    "model.train(10, ds_train, callbacks=[LossMonitor(per_print_times=ds_train.get_dataset_size())], dataset_sink_mode=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "1a0baebc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test accuracy is 1.0\n"
     ]
    }
   ],
   "source": [
    "x = model.predict(ms.Tensor(X_test)).asnumpy()\n",
    "pred = np.round(1 / (1 + np.exp(-x)))\n",
    "correct = np.equal(pred, Y_test)\n",
    "acc = np.mean(correct)\n",
    "print('Test accuracy is', acc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a56b7216",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "MindSpore(1.5.0)",
   "language": "python",
   "name": "mindspore"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
